#pragma once

#include <cstdint>
#include <vector>
#include <string>

/// TGA format specification
/// brief:
/// http://www.paulbourke.net/dataformats/tga/
/// full:
/// https://www.ludorg.net/amnesia/TGA_File_Format_Spec.html
/// https://www.dca.fee.unicamp.br/~martino/disciplinas/ea978/tgaffs.pdf

// TGA uses intel byte ordering

#pragma pack(push, 1)
struct TGA_Header
{
	uint8_t idlength = 0;
	uint8_t colormaptype = 0;
	uint8_t imagetype = 0;
	uint16_t firstentryindex = 0;
	uint16_t colormaplength = 0;
	uint8_t  colormapentrysize = 0;
	uint16_t x_origin = 0;
	uint16_t y_origin = 0;
	uint16_t imagewidth = 0;
	uint16_t imageheight = 0;
	uint8_t pixeldepth = 0;
	uint8_t imagedescriptor = 0;
};
static_assert(sizeof(TGA_Header) == 18, "wrong TGA header");

struct TGA_Image_Colormap_Data
{
	std::vector<uint8_t> imageid{ 0, 0 };
	std::vector<uint8_t> colormapdata{ 0, 0 };
	std::vector<uint8_t> imagedata{ 0, 0 };
};

struct TGA_Developarea
{
	std::vector<uint8_t> developfields{ 0, 0 };
	std::vector<uint8_t> developdirectory{ 0, 0 };
};

struct TGA_Extensionarea
{
	uint16_t extensionsize = 0;
	uint8_t authorname[41] = { 0 }; // ASCII
	uint8_t authorcomment[324] = { 0 }; // ASCII
	uint16_t datetimestamp = 0;
	uint8_t jobtime[3] = { 0 };
	uint8_t softwareid[41] = { 0 }; // ASCII
	uint8_t softwareversion[3] = { 0 };
	uint32_t keycolor = 0;
	uint16_t pixelaspectratio[2] = { 0 };
	uint16_t gammavalue[2] = { 0 };
	uint32_t colorcorrectionoffset = { 0 };
	uint32_t pastagestampoffset = { 0 };
	uint32_t scanlineoffset = { 0 };
	uint8_t attributetype = { 0 };
	std::vector<uint8_t> scanlinetable = { 0, 0};
	std::vector<uint8_t> patagestampimage = { 0, 0 };
	uint16_t colorcorrectiontable[1024] = { 0 }; // 1K
};

static const std::string newtgasignature = "TRUEVISION-XFILE.";
struct TGA_Footer
{
	uint32_t extensionareaoffset = 0;
	uint32_t developdirectoryoffset = 0;
	uint8_t signature[17 + 1] = { 0 }; // +1 for NUL-byte
};

struct TGAFileBuffer
{
	TGA_Header header;
	TGA_Image_Colormap_Data data;
	TGA_Developarea developarea;
	TGA_Extensionarea extensionarea;
	TGA_Footer footer;
};

#pragma pack(pop)

